package com.fiap.bo;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import com.fiap.dao.ClienteDAO;
import com.fiap.dao.ColaboradorDAO;
import com.fiap.dao.ContaClienteDAO;
import com.fiap.dao.EnderecoDAO;
import com.fiap.dao.EstoqueDAO;
import com.fiap.dao.FornecedorDAO;
import com.fiap.dao.Manager;
import com.fiap.dao.ModeloCarroDAO;
import com.fiap.dao.OrdemServicoDAO;
import com.fiap.dao.PagadorDAO;
import com.fiap.dao.PecaDAO;
import com.fiap.dao.RecebimentoDAO;
import com.fiap.dao.TelefoneDAO;
import com.fiap.dao.TipoRecedimentoDAO;
import com.fiap.dao.VeiculoDAO;
import com.fiap.dao.impl.ClienteDAOImpl;
import com.fiap.dao.impl.ColaboradorDAOImpl;
import com.fiap.dao.impl.ContaClienteDAOImpl;
import com.fiap.dao.impl.EnderecoDAOImpl;
import com.fiap.dao.impl.EstoqueDAOImpl;
import com.fiap.dao.impl.FornecedorDAOImpl;
import com.fiap.dao.impl.ModeloCarroDAOImpl;
import com.fiap.dao.impl.OrdemServicoDAOImpl;
import com.fiap.dao.impl.PagadorDAOImpl;
import com.fiap.dao.impl.PecaDAOimpl;
import com.fiap.dao.impl.RecebimentoDAOImpl;
import com.fiap.dao.impl.TelefoneDAOImpl;
import com.fiap.dao.impl.TipoRecebimentoDAOImpl;
import com.fiap.dao.impl.VeiculoDAOImpl;
import com.fiap.to.ClienteTO;
import com.fiap.to.ColaboradorTO;
import com.fiap.to.ContaClienteTO;
import com.fiap.to.EnderecoTO;
import com.fiap.to.EstoqueTO;
import com.fiap.to.FornecedorTO;
import com.fiap.to.ModeloCarroTO;
import com.fiap.to.OrdemServicoTO;
import com.fiap.to.PagadorTO;
import com.fiap.to.PecaOsTO;
import com.fiap.to.PecaTO;
import com.fiap.to.RecebimentoTO;
import com.fiap.to.TelefoneTO;
import com.fiap.to.TipoRecebimentoTO;
import com.fiap.to.VeiculoTO;

@ManagedBean
@SessionScoped
public class AmBO {
	EntityManagerFactory factory = Manager.getInstance();
	EntityManager em = factory.createEntityManager();

	FacesContext fc = FacesContext.getCurrentInstance();


	public List<ClienteTO> buscarTodosCliente() {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		List<ClienteTO> listaClientes = new ArrayList<ClienteTO>();

		listaClientes = clienteDao.buscarTodosClientes();

		return listaClientes;
	};

	public List<VeiculoTO> buscarVeiculoPorPlaca(String placa) {
		VeiculoDAO veiculoDao = new VeiculoDAOImpl(em);
		List<VeiculoTO> listaVeiculos = new ArrayList<VeiculoTO>();

		listaVeiculos = veiculoDao.buscarVeiculoPorPlaca(placa);

		return listaVeiculos;
	};

	public void atualizarVeiculo(VeiculoTO veiculo) {
		VeiculoDAO veiculoDao = new VeiculoDAOImpl(em);

		veiculoDao.update(veiculo);
	}

	public List<ClienteTO> buscarClientePorNome(String nome) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		List<ClienteTO> listaClientes = new ArrayList<ClienteTO>();

		listaClientes = clienteDao.buscarClientePorNome(nome);

		return listaClientes;
	}

	public List<ClienteTO> buscarClientePorApelido(String apelido) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		List<ClienteTO> listaClientes = new ArrayList<ClienteTO>();

		listaClientes = clienteDao.buscarClientePorApelido(apelido);

		return listaClientes;
	}

	public List<ClienteTO> buscarClientePorNomeApelido(String busca) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		List<ClienteTO> listaClientes = new ArrayList<ClienteTO>();

		listaClientes = clienteDao.buscarClientePorNomeApelido(busca);

		return listaClientes;
	}

	public ClienteTO buscarClientePorRG(String rg) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		ClienteTO cliente = new ClienteTO();

		cliente = clienteDao.buscarClientePorRG(rg);

		return cliente;
	}

	public ClienteTO buscarClientePorCPF(String cpf) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		ClienteTO cliente = new ClienteTO();

		cliente = clienteDao.buscarClientePorCPF(cpf);

		return cliente;
	}

	public List<ClienteTO> buscarClientePorIndicacao(String indicacao) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);
		List<ClienteTO> listaClientes = new ArrayList<ClienteTO>();

		listaClientes = clienteDao.buscarClientePorIndicacao(indicacao);

		return listaClientes;
	}

	public ContaClienteTO buscarSaldoCliente(int id_cliente) {
		ContaClienteDAO contaClienteDao = new ContaClienteDAOImpl(em);
		ContaClienteTO contaCliente = new ContaClienteTO();

		contaCliente = contaClienteDao.buscarSaldoCliente(id_cliente);

		return contaCliente;
	}

	public void atualizarCliente(ClienteTO cliente) {
		ClienteDAO ClienteDao = new ClienteDAOImpl(em);

		ClienteDao.update(cliente);
	}

	public List<OrdemServicoTO> buscarOsPorCarro(int id_veiculo) {
		OrdemServicoDAO ordemServicoDao = new OrdemServicoDAOImpl(em);
		List<OrdemServicoTO> listaOS = new ArrayList<OrdemServicoTO>();

		listaOS = ordemServicoDao.buscarOsPorCarro(id_veiculo);

		return listaOS;
	}

	public List<OrdemServicoTO> buscarTodasOsSemCliente() {
		OrdemServicoDAO ordemServicoDao = new OrdemServicoDAOImpl(em);
		List<OrdemServicoTO> listaOS = new ArrayList<OrdemServicoTO>();

		listaOS = ordemServicoDao.buscarTodasOsSemCliente();

		return listaOS;
	}

	public List<PecaTO> buscarTodosPecas() {
		PecaDAO pecaDao = new PecaDAOimpl(em);
		List<PecaTO> listaPecas = new ArrayList<PecaTO>();

		listaPecas = pecaDao.buscarTodosPecas();

		return listaPecas;
	}

	public List<PecaTO> buscaPecaPorFabricante(String fabricante) {
		PecaDAO pecaDao = new PecaDAOimpl(em);
		List<PecaTO> listaPecas = new ArrayList<PecaTO>();

		listaPecas = pecaDao.buscaPecaPorFabricante(fabricante);

		return listaPecas;
	}

	public List<PecaTO> buscaPecaPorModelo(String modelo) {
		PecaDAO pecaDao = new PecaDAOimpl(em);
		List<PecaTO> listaPecas = new ArrayList<PecaTO>();

		listaPecas = pecaDao.buscaPecaPorModelo(modelo);

		return listaPecas;
	}

	public List<PecaTO> buscaPecaPorFornecedor(int id_fornecedor) {
		PecaDAO pecaDao = new PecaDAOimpl(em);
		List<PecaTO> listaPecas = new ArrayList<PecaTO>();

		listaPecas = pecaDao.buscaPecaPorFornecedor(id_fornecedor);

		return listaPecas;
	}

	public void atulizarPeca(PecaTO peca) {
		PecaDAO pecaDao = new PecaDAOimpl(em);

		if (peca.getQntMinima() > 0) {
			pecaDao.update(peca);
		}
	}

	public List<PagadorTO> buscarTodosPagadores() {
		PagadorDAO pagadorDao = new PagadorDAOImpl(em);
		List<PagadorTO> listaPagadores = new ArrayList<PagadorTO>();

		listaPagadores = pagadorDao.buscarTodosPagadores();

		return listaPagadores;
	}

	public List<RecebimentoTO> buscarRecebimentosPorPagador(int id_pagador) {
		RecebimentoDAO recebimentoDao = new RecebimentoDAOImpl(em);
		List<RecebimentoTO> listaRecebimentos = new ArrayList<RecebimentoTO>();

		listaRecebimentos = recebimentoDao
				.buscarRecebimentosPorPagador(id_pagador);

		return listaRecebimentos;
	}

	public List<RecebimentoTO> buscarRecebimentosPorCliente(int id_cliente) {
		RecebimentoDAO recebimentoDao = new RecebimentoDAOImpl(em);
		List<RecebimentoTO> listaRecebimentos = new ArrayList<RecebimentoTO>();

		listaRecebimentos = recebimentoDao
				.buscarRecebimentosPorCliente(id_cliente);

		return listaRecebimentos;
	}

	public List<RecebimentoTO> buscarRecebimentosPorOs(int id_os) {
		RecebimentoDAO recebimentoDao = new RecebimentoDAOImpl(em);
		List<RecebimentoTO> listaRecebimentos = new ArrayList<RecebimentoTO>();

		listaRecebimentos = recebimentoDao.buscarRecebimentosPorOs(id_os);

		return listaRecebimentos;
	}

	public List<RecebimentoTO> buscarRecebimentosPorData(Calendar data1,
			Calendar data2) {
		RecebimentoDAO recebimentoDao = new RecebimentoDAOImpl(em);
		List<RecebimentoTO> listaRecebimentos = new ArrayList<RecebimentoTO>();

		listaRecebimentos = recebimentoDao.buscarRecebimentosPorData(data1,
				data2);

		return listaRecebimentos;
	}

	public List<TelefoneTO> buscarTelefonesPorClienteId(int id_cliente) {
		TelefoneDAO telefoneDao = new TelefoneDAOImpl(em);
		List<TelefoneTO> listaTelefone = new ArrayList<TelefoneTO>();

		listaTelefone = telefoneDao.buscarTelefonesPorClienteId(id_cliente);

		return listaTelefone;
	}

	public List<EnderecoTO> buscarEnderecoPorClienteId(int id_cliente) {
		EnderecoDAO enderecoDao = new EnderecoDAOImpl(em);
		List<EnderecoTO> listaEnderecos = new ArrayList<EnderecoTO>();

		listaEnderecos = enderecoDao.buscarEnderecoPorClienteId(id_cliente);

		return listaEnderecos;
	}

	public void atualizarTelefone(TelefoneTO telefone) {
		TelefoneDAO telefoneDao = new TelefoneDAOImpl(em);

		telefoneDao.update(telefone);
	}

	public void atualizarEndereco(EnderecoTO endereco) {
		EnderecoDAO enderecoDao = new EnderecoDAOImpl(em);

		enderecoDao.update(endereco);
	}

	public List<PecaTO> buscarPecaPorFabricanteeTipo(String fabricante,
			String tipo) {
		PecaDAO pecaDao = new PecaDAOimpl(em);
		List<PecaTO> listaPecas = new ArrayList<PecaTO>();

		listaPecas = pecaDao.buscarPecaPorFabricanteeTipo(fabricante, tipo);

		return listaPecas;
	}

	public List<RecebimentoTO> buscarRecebimentoPorOS(int id_os) {
		RecebimentoDAO recebimentoDao = new RecebimentoDAOImpl(em);
		List<RecebimentoTO> listaRecebimentos = new ArrayList<RecebimentoTO>();

		listaRecebimentos = recebimentoDao.buscarRecebimentosPorOs(id_os);

		return listaRecebimentos;
	}

	public List<ModeloCarroTO> buscarModelosPorMarca(int id_marca) {
		ModeloCarroDAO modeloDao = new ModeloCarroDAOImpl(em);
		List<ModeloCarroTO> listaModelos = new ArrayList<ModeloCarroTO>();

		listaModelos = modeloDao.buscarModelosPorMarca(id_marca);

		return listaModelos;
	}

	public String cadastrarVeiculo(VeiculoTO veiculo) {
		VeiculoDAO veiculoDao = new VeiculoDAOImpl(em);
		String retorno = "";

		if (!veiculo.getDono().equals(null)) {
			FacesMessage mensagem = new FacesMessage();
			fc.addMessage("", mensagem);
			return retorno = "";
		} else {
			FacesMessage mensagem = new FacesMessage();
			fc.addMessage("", mensagem);
			veiculoDao.insert(veiculo);
			retorno = "";
		}

		return retorno;
	}

	public List<VeiculoTO> buscarTodosCarros() {
		VeiculoDAO veiculoDao = new VeiculoDAOImpl(em);
		List<VeiculoTO> listaVeiculos = new ArrayList<VeiculoTO>();

		listaVeiculos = veiculoDao.buscarTodosCarros();

		return listaVeiculos;
	}

	public String cadastrarEndereco(EnderecoTO endereco) {
		EnderecoDAO enderecoDao = new EnderecoDAOImpl(em);
		String retorno = "";
		
		if(!endereco.getPessoa().equals(null)){
			FacesMessage mensagem = new FacesMessage();
			fc.addMessage("", mensagem);
			return retorno = "";
		} else {
			FacesMessage mensagem = new FacesMessage();
			fc.addMessage("", mensagem);
			enderecoDao.insert(endereco);
			retorno = "";
		}
		
		return retorno;
	}
	

	public String cadastrarTelefone(TelefoneTO telefone) {
		TelefoneDAO telefoneDao = new TelefoneDAOImpl(em);
		String retorno = "";
		
		if(!telefone.getPessoa().equals(null)){
			FacesMessage mensagem = new FacesMessage();
			fc.addMessage("", mensagem);
			return retorno = "";
		} else {
			FacesMessage mensagem = new FacesMessage();
			fc.addMessage("", mensagem);
			telefoneDao.insert(telefone);
			retorno = "";
		}
		
		return retorno;
	}

	public void atualizarEstoque(List<PecaTO> pecas) {
		PecaDAO pecaDao = new PecaDAOimpl(em);

		for (PecaTO peca : pecas) {
			pecaDao.update(peca);
		}
	}

	public void cadastrarFornecedor(FornecedorTO fornecedor) {
		FornecedorDAO fornecedorDao = new FornecedorDAOImpl(em);

		fornecedorDao.insert(fornecedor);
	}

	public void cadastroFuncionado(ColaboradorTO colaborador) {
		ColaboradorDAO colaboradorDao = new ColaboradorDAOImpl(em);

		colaboradorDao.insert(colaborador);
	}
/*
	public void cadastrarModelo(ModeloCarroTO modelo) {
		ModeloCarroDAO modeloDao = new ModeloCarroDAOImpl(em);

		modeloDao.insert(modelo);
	}

	public void atualizarModelo(ModeloCarroTO modelo) {
		ModeloCarroDAO modeloDao = new ModeloCarroDAOImpl(em);

		modeloDao.update(modelo);
	}
*/
	// RN03
	// RN10
	// RN11
	public  String cadastrarOS(OrdemServicoTO os) {
		EstoqueDAO estoqueDao = new EstoqueDAOImpl(em);
		EstoqueTO estoque = new EstoqueTO();
		OrdemServicoDAO osDao = new OrdemServicoDAOImpl(em);
		String retorno = "";

		for (PecaOsTO pecaOs : os.getPecas()) {
			estoque = estoqueDao.buscarEstoquePorPeca(pecaOs.getPeca()
					.getId_peca());
			if (estoque.getQtdEstoque() > pecaOs.getQuantidade()) {
				estoque.setQtdEstoque(estoque.getQtdEstoque()
						- pecaOs.getQuantidade());
				estoqueDao.update(estoque);
			} else {
				FacesMessage mensagem = new FacesMessage();
				fc.addMessage("", mensagem);
				retorno = "";
			}
		}

		osDao.insert(os);

		return retorno;
	}

	// RN03
	// RN10
	// RN11
	public String atualizarOS(OrdemServicoTO os) {
		OrdemServicoDAO osDao = new OrdemServicoDAOImpl(em);
		EstoqueDAO estoqueDao = new EstoqueDAOImpl(em);
		OrdemServicoTO os_old = new OrdemServicoTO();
		PecaOsTO peca_old = new PecaOsTO();
		EstoqueTO estoque = new EstoqueTO();
		int quantidade = 0;
		String retorno = "";
		
		os_old = osDao.searchById(os.getId_os());

		for (PecaOsTO pecaOs : os.getPecas()) {
			estoque = estoqueDao.buscarEstoquePorPeca(pecaOs.getPeca().getId_peca());
			
			for(PecaOsTO pecaOsOld : os_old.getPecas()){
				if(pecaOsOld.getId_pecaOs() == pecaOs.getId_pecaOs()){
					peca_old = pecaOsOld;
				}
			}
			
			if (peca_old.getQuantidade() > pecaOs.getQuantidade() ) {
				quantidade = peca_old.getQuantidade() - pecaOs.getQuantidade();
				
				estoque.setQtdEstoque(estoque.getQtdEstoque()
						+ quantidade);
				estoqueDao.update(estoque);
			} else if (peca_old.getQuantidade() < pecaOs.getQuantidade() ) {
				quantidade = pecaOs.getQuantidade() - peca_old.getQuantidade();
				
				if(estoque.getQtdEstoque() > quantidade){
					estoque.setQtdEstoque(estoque.getQtdEstoque()
							- pecaOs.getQuantidade());
					estoqueDao.update(estoque);
				} else if (!os.getAtendente().equals(null)) {
					FacesMessage mensagem = new FacesMessage();
					fc.addMessage("", mensagem);
					return retorno = "";
				}
			}
			
			peca_old = new PecaOsTO();
		}

		osDao.insert(os);

		return retorno;
	}

	public void cadastrarPagador(PagadorTO pagador) {
		PagadorDAO pagadorDao = new PagadorDAOImpl(em);

		pagadorDao.insert(pagador);
	}

	// RN07
	public void cadastrarPeca(PecaTO peca) {
		PecaDAO pecaDao = new PecaDAOimpl(em);

		if (peca.getQntMinima() > 0) {
			pecaDao.insert(peca);
		}
	}

	// RN14
	// RN16
	public String cadastrarRecebimento(RecebimentoTO recebimento) {
		RecebimentoDAO recebimentoDao = new RecebimentoDAOImpl(em);
		ContaClienteDAO contaDao = new ContaClienteDAOImpl(em);
		ContaClienteTO conta = new ContaClienteTO();
		String retorno = "";

		if (!recebimento.getOs().equals(null) && recebimento.getPagador().equals(null) && recebimento.getCliente().equals(null)) {
			recebimentoDao.insert(recebimento);
		} else if (recebimento.getOs().equals(null) && !recebimento.getPagador().equals(null) && recebimento.getCliente().equals(null)) {
			conta = contaDao.buscarSaldoCliente(recebimento.getPagador()
					.getCliente().getId_cliente());
			if (conta.getSaldo() >= recebimento.getQntPago()) {
				conta.setSaldo(conta.getSaldo() - recebimento.getQntPago());
				contaDao.update(conta);
				recebimentoDao.insert(recebimento);
			} else {
				FacesMessage mensagem = new FacesMessage();
				fc.addMessage("", mensagem);
				return retorno = "";
			}
		} else if (recebimento.getOs().equals(null) && recebimento.getPagador().equals(null) && !recebimento.getCliente().equals(null)) {
			conta = contaDao.buscarSaldoCliente(recebimento.getCliente()
					.getId_cliente());
			if (conta.getSaldo() >= recebimento.getQntPago()) {
				conta.setSaldo(conta.getSaldo() - recebimento.getQntPago());
				contaDao.update(conta);
				recebimentoDao.insert(recebimento);
			} else {
				FacesMessage mensagem = new FacesMessage();
				fc.addMessage("", mensagem);
				return retorno = "";
			}
		}
		
		return retorno;
	}

	public EstoqueTO buscarEstoquePorPeca(int id_peca) {
		EstoqueDAO estoqueDao = new EstoqueDAOImpl(em);
		EstoqueTO estoque = new EstoqueTO();

		estoque = estoqueDao.buscarEstoquePorPeca(id_peca);

		return estoque;
	}

	public List<EstoqueTO> buscarTodoEstoque() {
		EstoqueDAO estoqueDao = new EstoqueDAOImpl(em);
		List<EstoqueTO> listaEstoque = new ArrayList<EstoqueTO>();

		listaEstoque = estoqueDao.buscarTodoEstoque();

		return listaEstoque;
	}

	// RN01
	public void cadastrarCliente(ClienteTO cliente) {
		ClienteDAO clienteDao = new ClienteDAOImpl(em);

		if (cliente.getCarros().size() > 0) {
			clienteDao.insert(cliente);
		}
	}

	// RN05
	public List<TipoRecebimentoTO> buscarContasAtivas() {
		TipoRecedimentoDAO tipoRecebimentoDao = new TipoRecebimentoDAOImpl(em);
		List<TipoRecebimentoTO> listaTiposRecebimentos = new ArrayList<TipoRecebimentoTO>();
		List<TipoRecebimentoTO> listaTiposRecebimentosAtivas = new ArrayList<TipoRecebimentoTO>();

		listaTiposRecebimentos = tipoRecebimentoDao
				.buscarTodosTiposRecebimentos();

		for (TipoRecebimentoTO tipo : listaTiposRecebimentos) {
			if (tipo.isAtivo() == true) {
				listaTiposRecebimentosAtivas.add(tipo);
			}
		}

		return listaTiposRecebimentosAtivas;
	}

}